package lk.icta.common.web;


import lk.icta.common.AppConstants;
import lk.icta.common.dao.DistrictDAO;
import lk.icta.common.dto.GeoPoint;
import lk.icta.common.entity.Document;
import lk.icta.common.entity.DocumentCategory;
import lk.icta.common.service.DocumentManagementService;
import lk.icta.common.service.GISService;
import lk.icta.common.util.KmlWriter;
import lk.icta.core.entity.*;
import lk.icta.core.service.*;
import lk.icta.user.entity.User;
import lk.icta.user.service.UserManager;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;


/**
 * @author Kusal Samarakoon
 */
public class JSONGPSImageService extends HttpServlet {

    private static final Logger logger = LoggerFactory.getLogger(JSONGPSImageService.class);


    private LandApplicationManagementService landApplicationManagementService;
    private LandManagementService landManagementService;
    private GISService gisService;
    private UserManager userManager;
    private DocumentManagementService documentManagementService;
    private final ObjectMapper mapper = new ObjectMapper();

    String landId;
    String type;


    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
        userManager = (UserManager) context.getBean("userManager");
        landApplicationManagementService = (LandApplicationManagementService) context.getBean("landApplicationManagementService");
        landManagementService = (LandManagementService) context.getBean("landManagementService");
        gisService = (GISService) context.getBean("gISService");
        documentManagementService = (DocumentManagementService) context.getBean("documentManagementService");

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        landId = request.getParameter("id");
        type = request.getParameter("type");

        //TODO : refactore the entire code

        HashMap<String, Object> optionLists;
        try {
            logger.debug("GPS Image");
            HttpSession session = request.getSession(false);
            if (session != null) {
                User user = (User) session.getAttribute(AppConstants.SESSION_USER_BEAN);
                optionLists = new HashMap<String, Object>();
                List<String> noGeoPointList = new ArrayList<String>();
                HashMap<String,GeoPoint>  geoPointHashMap = new HashMap<String, GeoPoint>();
             //   List<String> docIdList = new ArrayList<String>();
                List<Document> docIdList = new ArrayList<Document>();
                if (type.equals("GPSImage")) {
                    logger.debug("GPS Image validate by {}", user.getUsername());
                    logger.debug("GPS Image landId  {}", landId);
                    logger.debug("GPS Image type {}", type);

                    long id = Long.parseLong(landId);
                    Land land = landManagementService.getLandByIdUKey(id, user);
                    if (land != null) {
                        logger.debug("GPS Image landName  {}", land.getNameOfTheLand());
                        List<Document> docList;

                        if (land.getInitialRecordId() != 0) {    // update detailed land
                            docList = documentManagementService.getDocumentsByModuleAndModuleId(user, ModuleType.DETAILED_LAND, id);
                        } else {  //add detailed land
                            docList = documentManagementService.getDocumentsByModuleAndModuleId(user, ModuleType.INITIAL_LAND, id);
                        }

                        GeoPoint geoPoint = null;
                        boolean isLandImageAttached = false;
                        if (docList != null && docList.size() > 0) {
                            logger.debug("GPS Image docList.size()  {}", docList.size());

                            for (Document document : docList) {
                                if (document.getDocumentCategory() != null && document.getDocumentCategory().getCategoryName().equals(AppConstants.LAND_IMAGE_DOC_CATEGORY)) {
                                    isLandImageAttached = true;
                                    logger.debug("GPS Image Image Name  {}", document.getDocumentName());
                                    logger.debug("GPS Image Image path  {}", document.getLocation());
                                    String path = document.getLocation() + document.getId() + document.getExtension();
                                    logger.debug("GPS Image Fullpath  {}", path);

                                    geoPoint = gisService.getGeoLocation(user, path);

                                    if (geoPoint != null) {
                                        if (geoPoint.getLatitude() != null && geoPoint.getLongitude() != null) {
                                            logger.debug("GPS Image Lat  {}", geoPoint.getLatitude());
                                            logger.debug("GPS Image Lon  {}", geoPoint.getLongitude());
                                            logger.debug("GPS Image Alt  {}", geoPoint.getAltitude());
                                            geoPointHashMap.put(document.getDocumentName(),geoPoint);
                                           // docIdList.add(String.valueOf(document.getId()));
                                            docIdList.add(document);
                                            logger.debug("Document name {} and {}",document.getDocumentName(),document.getFileName());
                                            //  break;
                                        }
                                    } else {
                                        noGeoPointList.add(document.getDocumentName());
                                    }
                                }
                            }

                        }


                        if(! isLandImageAttached) {
                            optionLists.put("msg", "No land image attached to this land");
                        }

                        optionLists.put("GPSMap", geoPointHashMap);
                        optionLists.put("NoGeoPointList",noGeoPointList);
                        optionLists.put("DocIdList",docIdList);
                    }
                }
            } else {
                logger.warn("User not logged in");
                return;
            }

        } catch (Exception e) {
            logger.error("Fatal Error", e);
            e.printStackTrace();
            return;
        }

        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();

        mapper.writeValue(out, optionLists);
        out.flush();
    }


}

